package com.lottery.common.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lottery.common.contants.Constants;
import com.lottery.common.contants.ReQueryResult;
import com.lottery.common.contants.RedisConstants;
import com.lottery.common.dao.MemberInfoMapper;
import com.lottery.common.dao.SysConfigMapper;
import com.lottery.common.entity.MemberInfo;
import com.lottery.common.entity.SysConfig;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.nutz.lang.util.NutMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static com.lottery.common.contants.Constants.TOKEN_ERROE;

@Slf4j
@Service
public class RedisUtils {
    /**
     * 使用redis判断用户是否连续点击，间隔{timeout}秒
     * @param redisTemplate
     * @param key 用户唯一标识符 例： payment+userId
     * @param timeout 阻隔时间
     * @return
     */
    @Resource
    private  SysConfigMapper configMapper;
    private static SysConfigMapper sysConfigMapper;

    @Resource
    private MemberInfoMapper mMapper;
    private static MemberInfoMapper memberMapper;



//    @Resource
//    private GrowthInfoMapper gMapper;
//    private static GrowthInfoMapper growthInfoMapper;

    @Autowired
    private  StringRedisTemplate redisTemplate;
    private static StringRedisTemplate stringRedisTemplate;

    @PostConstruct
    public void init() {
        log.info("init redisTemplate");
        sysConfigMapper= this.configMapper;
        stringRedisTemplate= this.redisTemplate;
    }

    /**
     *
     * @param redisTemplate
     * @param key
     * @param timeout 秒
     * @return
     */
    public static boolean checkRedisLock(StringRedisTemplate redisTemplate, String key, Integer timeout) {
        boolean flag=redisTemplate.opsForValue().setIfAbsent(key,key,timeout, TimeUnit.SECONDS);
        return flag;
    }

    /**
     * 判断redis锁是否存在 不存在则添加指定时限 锁
     * @param key
     * @param timeout 单位 秒
     * @return
     */
    public static boolean checkRedisLock(String key, Integer timeout) {
        boolean flag=stringRedisTemplate.opsForValue().setIfAbsent(key,key,timeout, TimeUnit.SECONDS);
        return flag;
    }

    //根据code获取 tb_sys_config 对象
    public static  <T> T  getConfigFromRedis( String code, Class<T> pojoCalss){
        Object object = stringRedisTemplate.opsForHash().get(RedisConstants.SYS_CONFIG,code);
        if (object==null){
            SysConfig param = new SysConfig();
            param.setCode(code);
            QueryWrapper<SysConfig> queryWrapper = new QueryWrapper<>(param);
            SysConfig sysConfig=sysConfigMapper.selectOne(queryWrapper);
            String json=JSON.toJSONString(sysConfig);
            stringRedisTemplate.opsForHash().putIfAbsent(RedisConstants.SYS_CONFIG,code,json);
            return  JSON.parseObject(json,pojoCalss);
        }else {
            return JSON.parseObject(object.toString(),pojoCalss);
        }
    }

    //根据code获取 tb_sys_config 对象
    public static ReQueryResult setConfigFromRedis(SysConfig sysConfig){
        ReQueryResult result=new ReQueryResult();
        result.error(Constants.INSIDE_WRONG_DESC);
//        stringRedisTemplate.opsForHash().put(RedisConstants.SYS_CONFIG,sysConfig.getCode(),"");
        int count=sysConfigMapper.updateById(sysConfig);
        if (count>0){
            stringRedisTemplate.opsForHash().put(RedisConstants.SYS_CONFIG,sysConfig.getCode(),JSON.toJSONString(sysConfig));
            QueryWrapper<SysConfig> queryWrapper = new QueryWrapper<>();
            String type=sysConfig.getCode().substring(0,2);
            queryWrapper.eq("type",type);
            queryWrapper.orderByAsc("code");
            List<SysConfig> sysConfigs=sysConfigMapper.selectList(queryWrapper);
            String json=JSON.toJSONString(sysConfigs);
            stringRedisTemplate.opsForHash().put(RedisConstants.SYS_CONFIG,type,json);

            result.success(Constants.SUCCESS_DESC);
        }
        return result;
    }

    //type tb_sys_config list 对象
    public static  <T> List<T> getConfigFromRedisByType(String type, Class<T> pojoCalss){
        Object object = stringRedisTemplate.opsForHash().get(RedisConstants.SYS_CONFIG,type);
        if (object==null){
            QueryWrapper<SysConfig> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("type",type);
            queryWrapper.orderByAsc("code");
            List<SysConfig> sysConfigs=sysConfigMapper.selectList(queryWrapper);
            String json=JSON.toJSONString(sysConfigs);
            stringRedisTemplate.opsForHash().put(RedisConstants.SYS_CONFIG,type,json);
            return  JSON.parseArray(json,pojoCalss);
        }else {
            return JSON.parseArray(object.toString(),pojoCalss);
        }
    }


    public static NutMap  getWxConfigFromRedis(){
        Object object = stringRedisTemplate.opsForValue().get(RedisConstants.WEIXIN_CONFIG);
        if (object==null){
            SysConfig param = new SysConfig();
            param.setCode("1201");
            QueryWrapper<SysConfig> queryWrapper = new QueryWrapper<>(param);
            return  JSON.parseObject(JSON.toJSONString(sysConfigMapper.selectOne(queryWrapper).getValue()),NutMap.class);
        }else {
            return JSON.parseObject(object.toString(),NutMap.class);
        }
    }


    public static Long selectMemberIdFromRedis(String phone,String token){
        Object o=null;
        Object o2=null;
        try {
            o=stringRedisTemplate.opsForHash().get(RedisConstants.LOGIN_APP,phone);
            o2=stringRedisTemplate.opsForHash().get(RedisConstants.LOGIN_MEMBER,o);
            if (o==null|| StringUtils.isEmpty(o.toString())||
                    o2==null||StringUtils.isEmpty(o2.toString())||!o.toString().equals(token)){
                MemberInfo param = new MemberInfo();
                param.setPhone(phone);
                param.setBaseToken(token);
                QueryWrapper<MemberInfo> queryWrapper = new QueryWrapper<>(param);
                MemberInfo member=memberMapper.selectOne(queryWrapper);
                if (member==null){
                    log.info(TOKEN_ERROE);
                    return  0L;
                }
                return  member.getId();
            }
        }catch (Exception e){
            log.info(TOKEN_ERROE);
            return  0L;
        }
        return Long.valueOf(o2.toString());
    }



    public static NutMap getLoginInfo(String phone){
        Logger logger = LoggerFactory.getLogger(RedisUtils.class);
        NutMap nutMap=null;
        Object o=null;
        try {
            o=stringRedisTemplate.opsForHash().get("loginMap",phone);
            if (o!=null&&StringUtils.isNotBlank(o.toString())){
                nutMap= JSONObject.parseObject(o.toString(),NutMap.class);
            }
        }catch (Exception e){
            logger.error(e.getMessage());
            logger.info(TOKEN_ERROE);
            return  nutMap;
        }
        logger.info("true token is {}",o);
        return nutMap;
    }



}
